package controller;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import javax.faces.context.FacesContext;
import model.dao.TaskDao;
import model.dao.SprintDao;
import model.domain.Project;
import model.domain.Sprint;
import model.domain.Task;
import org.openfaces.component.chart.ChartModel;
import org.openfaces.component.chart.PlainModel;
import org.openfaces.component.chart.PlainSeries;


public class chartBean {

    private Project project;

    public chartBean() {

    }

    public void setProject(Project object){
        this.project = object;
    }

    public Project getProject(){
	return this.project;
    }

    public ChartModel getCurrentSprintBurndownChart() throws ParseException {

        Map idealMap = new LinkedHashMap();
        Map currentMap = new LinkedHashMap();


        TaskDao home = new TaskDao();
        Sprint currentSprint = this.getCurrentSprint();
        if(currentSprint == null){
            idealMap.put(0, 0);
            PlainSeries series = new PlainSeries();
            series.setData(idealMap);

            //get message to show
            Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
            ResourceBundle bundle = ResourceBundle.getBundle(FacesContext.getCurrentInstance().getApplication().getMessageBundle(), locale);
            series.setKey(bundle.getString("no_data_show"));
            PlainModel model = new PlainModel();
            model.addSeries(series);
            return model;
        }
        Double sumEffort = home.sumEstimatedEffortBySprint(currentSprint).doubleValue();
        Double idealEffort = sumEffort;
        Double currentEffort = sumEffort;


        Long daysOnSprint = this.getDateDiffInDays(currentSprint.getStart(), currentSprint.getEnd()) + 1;

        Double average = idealEffort/daysOnSprint;

        List<Task> taskList = home.findBySprint(currentSprint);
        Calendar sprintDate = Calendar.getInstance();
        Calendar taskDate = Calendar.getInstance();
        Calendar now = Calendar.getInstance();
        String day;


        //for each day on the Sprint, get ideal and current Efforts to fill Sprint Burndown Chart
        for(int i = 0; i <= daysOnSprint; i++){
            sprintDate.setTime(currentSprint.getStart());
            sprintDate.add(Calendar.DATE, i);
            //normalize date
            sprintDate.set(Calendar.HOUR, 2);
            sprintDate.set(Calendar.MINUTE, 0);
            sprintDate.set(Calendar.SECOND, 0);

            day = String.valueOf(sprintDate.get(Calendar.DAY_OF_MONTH));

            //ideal => effort - average, for each day
            idealMap.put(day, idealEffort);

            //current => effort - task.effort, for each completed task, until today
            for (Task task : taskList){
                if(task.getEnd() != null){

                    System.out.println(task.getEnd());
                    taskDate.setTime(task.getEnd());
                    taskDate.set(Calendar.HOUR, 2);
                    taskDate.set(Calendar.MINUTE, 0);
                    taskDate.set(Calendar.SECOND, 0);
                    if(sprintDate.getTime().equals(taskDate.getTime())){
                        currentEffort = currentEffort - task.getEstimatedEffort();
                    }
                }
            }
            if(sprintDate.getTime().before(now.getTime())){
                currentMap.put(day,currentEffort);
            }

            idealEffort = idealEffort - average;
        }

        PlainSeries idealSeries = new PlainSeries();
        PlainSeries currentSeries = new PlainSeries();

        idealSeries.setData(idealMap);
        currentSeries.setData(currentMap);


        Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
        ResourceBundle bundle = ResourceBundle.getBundle(FacesContext.getCurrentInstance().getApplication().getMessageBundle(), locale);
        idealSeries.setKey(bundle.getString("ideal"));
        currentSeries.setKey(bundle.getString("current"));

        PlainModel chartModel = new PlainModel();
        chartModel.addSeries(idealSeries);
        chartModel.addSeries(currentSeries);
        return chartModel;
    }

    public Sprint getCurrentSprint() throws ParseException{
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        Calendar cal = Calendar.getInstance();
        Date now = dateFormat.parse(dateFormat.format(cal.getTime()));
        SprintDao home = new SprintDao();
        Sprint currentSprint = home.findByDate(now, this.project);
        return currentSprint;
    }

    private Long getDateDiffInDays(Date start, Date end){
        Long dateDiffInMilliseconds = end.getTime() - start.getTime();
        return dateDiffInMilliseconds/ (24 * 60 * 60 * 1000);
    }
}
